<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Menu extends AppModel {
    var $_primary_key = ADMIN_MENU_ID;
    var $_tablename = ADMIN_MENUS_TABLE;
    var $_mapping = array(
                           array('id' => ADMIN_MENU_ID),
                           array('name' => ADMIN_MENU_NAME),
                           array('parent_id' => ADMIN_MENU_PARENT_ID),
                           array('admin_menu_link' => ADMIN_MENU_LINK),
                           array('ordering' => ADMIN_MENU_ORDERING),
                           array('admin_menu_image' => ADMIN_MENU_IMAGE),
                           array('access_level' => ADMIN_MENU_ACCESS_LEVEL),
                            );
    var $_cache = 'menus_cache';
    var $_sort_field = 'ordering';
    var $_sort_type = 0;
    public function Menu($id = NULL){
        parent::AppModel($id);
    }
    /**
    * Get all children of a parent menu
    * @param : Parent menu id
    * @param : result
    * @param : Access level
    */
    public function menus_children($parent_id = 0, &$result, $level = NULL){
        $condition = ADMIN_MENU_PARENT_ID.' = '.$parent_id;
        if(!is_null($level))
            $condition .= ' AND '.ADMIN_MENU_ACCESS_LEVEL.' <= '.$level;
        $menus = $this->get_lists($condition , NULL, NULL, $this->_sort_field, $this->_sort_type);
        if(count($menus)==0)
            return;
        foreach($menus as $menu){
            $menu->children = array();
            $this->menus_children($menu->id, $menu->children, $level);
            $result[] = $menu;
        }
    }
    /**
    * Get top level menus
    * @param : Access level
    */
    public function menus_top($level = NULL){
        $condition = '('.ADMIN_MENU_PARENT_ID.' = 0 OR '.ADMIN_MENU_PARENT_ID.' IS NULL OR '.ADMIN_MENU_PARENT_ID.' = '.ADMIN_MENU_ID.')';
        if(!is_null($level))
            $condition .= ' AND '.ADMIN_MENU_ACCESS_LEVEL.' <= '.$level;
        $menus = $this->get_lists($condition, NULL, NULL, $this->_sort_field, $this->_sort_type);
        return $menus;
    }
    /**
    * Get all menus recursive
    * @param : Access level
    * @param : Use cache
    */
    public function menus_recursive($level = NULL, $cache=TRUE){
        $CI = &get_instance();
        if($cache && $CI->session->userdata($this->_cache)){
            $menus = $CI->session->userdata($this->_cache);
        }else{
            $menus = $this->menus_top($level);
            foreach($menus as &$menu){
                $menu->children = array();
                $this->menus_children($menu->id, $menu->children, $level);
            }
            if($cache)
                $CI->session->set_userdata($this->_cache, $menus);
        }
        return $menus;
    }
    function clear_cache(){
        $CI = &get_instance();
        $CI->session->unset_userdata($this->_cache);
    }
    /**
    * Get parent (and grandpa and ...) recursive of current menu item
    * @param : Access level
    * @param : Use cache
    */
    public function parent_recursive(){
        if(empty($this->parent_id))
            return array();
        $this->_parent_recursive($this->parent_id, $result);
        return array_reverse($result);
    }
    
    private function _parent_recursive($menu_id, &$result){
        $CI = &get_instance();
        $m = $CI->load->module_model_factory('menus.menu', $menu_id);
        $result[] = $m;
        if(empty($m->parent_id))
            return;
        else{
            $this->_parent_recursive($m->parent_id, $result);
        }
    }
    /**
    * Get all menus recursive in tree view
    */
    public function menu_list_tree(){
        $this->_sort_field = 'name';
        $this->_sort_type = 0;
        $menus = $this->menus_recursive(NULL, FALSE);
        foreach($menus as $m){
            $result[] = $m;
            $this->_build_tree($m->children, $m->name, $result);
        }
        return $result;
    }
    
    private function _build_tree($children, $name, &$result){
        foreach($children as &$child){
            $child->name = $name.' > '.$child->name;
            $result[] = $child;
            if($child->children)
                $this->_build_tree($child->children, $child->name, $result);
        }
    }
}
?>